        TITL DAI FIRMWARE 1EA0E-1EBFF  V1.0  Rev.1
        ORG   :EA0E
*
*
*
***************************************
* COPY OPERAND INTO REGISTERS B,C,D,E *
***************************************
*
* Entry: HL points to operand.
* Exit:  HL points to last byte of operand.
*        AF preserved.
*
L1E159  MOV   B,M
        INX   H
        MOV   C,M
        INX   H
        MOV   D,M
        INX   H
        MOV   E,M
        RET
*
************************************
* CLEAR MACC AND REGISTERS A,B,C,D *
************************************
*
AZERO   LXI   H,:00D5   Addr MACC
        XRA   A         )
        MOV   B,A       ) Clear ABCD
        MOV   C,A       )
        MOV   D,A       )
        JMP   :E9DB     Clear MACC
*
*************************
* FPT DIVIDE SUBROUTINE *
*************************
*
* MACC = MACC / MEM. Rounded quotient in MACC
* and registers ABCD, exponent in E.
*
* Entry: HL points to operand.
* Exit:  CY=1: Overflow, result invalid.
*        CY=0: Result in ABCD, EHL corrupted.
*
ADIV    CALL  :EBF4     Test if MEM=0; exp byte in A
        JZ    :EA54     Then run divide by 0 error
        PUSH  PSW       Save exp MEM
        ANI   :80       Sign bit only
        MOV   B,A       Preserve sign
        POP   PSW       Get exp MEM
        ANI   :7F       Skip sign bit
        CMA             ) 2-compl of exponent
        INR   A         )
        CPI   :C0       Overflow in sign bit ?
        JZ    :EA46     Then run overflow error
        ANI   :7F       Only compl. exp MEM
        ORA   B         Add sign
        CALL  :EB1D     Subtract exponents
        JC    :EA4B     Evt. run overflow error
        JZ    :EA16     If zero result: clear MACC +
 REM ABCD
        CALL  :EC4A     Run fixed division
        JNC   :EB06     Round up if no overflow
*
* If overflow:
*
OVERF   CALL  :C04B     Run overflow error
        STC             Flag error
        RET
*
******************
* ERROR HANDLING *
******************
*
* Entry: S=1: Overflow error.
*        S=0: Underflow error.
*        Z=1: Divide by zero error.
*
OVUNF   JM    :EA46     Evt run overflow error
UNDRF   CALL  :C065     Run underflow error
        JMP   :EA16     Clear MACC + ABCD
DIV0    CALL  :C06C     Run divide by 0 error
        STC             Flag error
        RET
*
*********************************
* FPT MULTIPLICATION SUBROUTINE *
*********************************
*
* MACC = MACC * MEM. Result in MACC and in
* registers A,B,C,D.
*
* Entry: HL points to operand in memory.
* Exit:  CY=1: Overflow; result invalid.
*        CY=0: Result in ABCD. EHL corrupted.
*
AMUL    CALL  :EBF4     Test if MEM=0; exp byte in A
        CNZ   :EB1D     Add exponents if not
        JC    :EA4B     Evt run error
        JZ    :EA16     Result 0: Clear MACC + ABCD
        CALL  :EC00     Multiply mantissa's
*
* Normalise if necessary:
*
        MOV   A,B       1st product
        ORA   A
        JMP   :EB00     Common exit with MUL/DIV
*
***************************
* FPT SUBTRACT SUBROUTINE *
***************************
*
* MACC = MACC - MEM.
*
* Entry: HL points to operand in memory.
* Exit:  CY=1: Overflow.
*        CY=0: Result in ABCD. EHL corrupted.
*
ASUB    MVI   B,:80     Mask to change sign of
 REM operand
        JMP   :EA74     Into AADD
*
**********************
* FPT ADD SUBROUTINE *
**********************
*
* MACC = MACC - MEM.
*
* Entry: HL points to operand in memory.
* Exit:  CY=1: Overflow.
*        CY=0: Result in ABCD. EHL corrupted.
*
AADD    MVI   B,:00     Zero mask
AD10    MVI   A,:7F     Most possible value
        STA   :00DE     Set MACC >> MEM
        CALL  :EBF4     Test if MEM =0; exp in A
        JZ    :E9F8     Then clear MACC + ABCD
        MOV   A,B       Get mask
        XRA   M         XOR with exp (ADD: gives
 REM exp; SUB: gives -exp)
        INX   H
        MOV   B,M       )
        INX   H         )
        MOV   C,M       ) Copy mantissa MEM into B
        INX   H         )
        MOV   D,M       )
        MOV   E,A       Exp in E
        LXI   H,:00D5   Addr MACC
        MOV   A,M       Get exp MACC
        XRA   E         XOR with exp MEM
        ANI   :80       Sign only
        STA   :00D9     Store #80 if different signs
        CALL  :EBF4     Test if MACC=0; exp in A
        JZ    :EB11     Jump if true
        PUSH  D
        MOV   A,E       Get exp MEM
        CALL  :C1E9     Sign extend
        MOV   E,A       Ext exp MEM in E
        MOV   A,M       Get exp MACC
        CALL  :C1E9     Sign extend
        SUB   E         Calc difference
        POP   D
        STA   :00DE     Save it
        JM    :EAB2     If exp MACC < exp MEM:
 REM exchange ABCD and MACC
        CPI   :19       Total bits in mantissa
        JC    :EAC6     OK if difference between
 REM both nrs <#19 in exp
        JMP   :E9F8     Else: Result is zero in
 REM MACC and ABCD
 REM
* Exchange MACC and ABCD:
 REM
L1E169  CPI   :E7       Total bits in mantissa
        JC    :EB16     If difference not too big
        MOV   M,E       Ext exp MEM in MACC
        CMA             )
        INR   A         ) A = ext exp old MACC
        INX   H
        MOV   E,M       ) Exchange 1st byte MACC
        MOV   M,B       ) mantissa and byte in B
        MOV   B,E       )
        INX   H
        MOV   E,M       ) Exchange 2nd byte MACC
        MOV   M,C       ) mantissa and byte in C
        MOV   C,E       )
        INX   H
        MOV   E,M       ) Exchange 3rd byte MACC
        MOV   M,D       ) mantissa and byte in D
        MOV   D,E       )
 REM Now orig MACC in ABCD and
 REM orig MEM in MACC
L1E170  MVI   E,:00
        CALL  :EB55     Shift BCDE right A places
        LDA   :00D9     Get result XOR sign bits
        ORA   A
        LXI   H,:00D8   Addr lobyte MACC
        JM    :EAEF     Jump if different signbits
 REM
* If both signs equal:
 REM
        MOV   A,M       )
        ADD   D         )
        MOV   D,A       )
        DCX   H         )
        MOV   A,M       ) Add mantissa MACC to BCD
        ADC   C         ) Result in BCD.
        MOV   C,A       )
        DCX   H         )
        MOV   A,M       )
        ADC   B         )
        MOV   B,A       )
        JNC   :EB06     Jump if no overflow
        CALL  :EB70     Else: shift BCDE right 1 bit
        CALL  :EBD9     Incr exponent
        JC    :EA46     Evt run overflow error
        JMP   :EB06     Round up
 REM
* If both signs not equal:
 REM
L1E171  XRA   A         )
        SUB   E         ) Compl exp in E
        MOV   E,A       )
        MOV   A,M       )
        SBB   D         )
        MOV   D,A       ) Subtract BCD from mantissa
        DCX   H         ) MACC. Result in BCD.
        MOV   A,M       )
        SBB   C         )
        MOV   C,A       )
        DCX   H         )
        MOV   A,M       )
        SBB   B         )
        MOV   B,A       )
        CC    :EB7D     Correct if overflow
AD10A   CP    :EB96     Evt normalize BCDE
        JP    :EA16     and clear MACC + ABCD
 REM
* Normal exit:
 REM
ADD11   CALL  :EBC3     Round up BCD, result in MACC
 REM exp in E
        JC    :EA46     Evt run overflow error
L1E174  MOV   A,E       Get exponent
        ORI   :01       Set flags on exp OR 1
        MOV   A,E       Exp in A
        RET
 REM
* If operand = 0:
 REM
L1E175  MVI   A,:80
        STA   :00DE     (00DE)=#80
L1E176  MOV   A,E       Get exponent
L1E177  CALL  :E9DB     Copy ABCD into MACC
        JMP   :EB0C     Take normal exit
*
**********************
* FPT: ADD EXPONENTS *
**********************
*
* Adds the exponent of the MACC to the exponent
* of a operand in memory.
*
* Entry: HL points to FPT number in memory.
*        A contains its exponent.
*        Other number in MACC.
* Exit:   Z=1:      MACC=0; HL=00D5
*        CY=1:      Overflow: HL=00D5; MACC pres.
*                   A: Sum of signed exponents SHL 1
*        Z=0, CY=0: O.K.: HL=00D5; sum of exponents
*                   in MACC.
*
MDEX    MOV   B,A       Exp MEM in B
        INX   H
        MOV   C,M       )
        INX   H         ) Copy mantissa MEM in CDE
        MOV   D,M       )
        INX   H         )
        MOV   E,M       )
        CALL  :EBF1     Test MACC=0; Exp MACC in A
        RZ              Abort if MACC=0, Z=1
        MOV   A,B       Get exp MEM in A
        CALL  :C1E9     Sign extend
        CALL  :C1BA     Add exponents, result in MAC
        RC              Abort if overflow, CY=1
        MOV   A,B       Get orig exp MEM
        ANI   :80       sign bit only
        XRA   M         Evt correct sign
        MOV   M,A       Exp back into MACC
        MVI   A,:01
        ORA   A
        RET
*
*********************************
* SHIFT BCDE LEFT (A) POSITIONS *
*********************************
*
* Exit: AF preserved.
*
LSHN    PUSH  PSW
        MOV   L,A       Nr of shifts in L
L1E180  DCR   L
        JM    :EB46     Abort if ready
        ORA   A         Clear CY
        CALL  :EB48     Shift BCDE left 1 position
        JMP   :EB3B     Next shift
L1E182  POP   PSW
        RET
*
*
*
*********************
* MULTIPLY BCDE * 2 *
*********************
*
* Shifts BCDE left 1 position. Entry CY goes to
* lsb of E.
*
* Exit: A corrupted, HL preserved.
*       F set on result.
*
L1E183  MOV   A,E
        RAL             Shift left E
        MOV   E,A
        MOV   A,D
        RAL             Shift left D
        MOV   D,A
        MOV   A,C
        RAL             Shift left C
        MOV   C,A
        MOV   A,B
        ADC   A         B=2*B+CY
        MOV   B,A
        RET
*
**********************************
* SHIFT BCDE RIGHT (A) POSITIONS *
**********************************
*
RSHN    MVI   L,:0008   Nr of shifts for 1 byte
L1E185  CMP   L
        JM    :EB64     Jump if A<8
 REM
* Shift 8 bits right:
 REM
        MOV   E,D       )
        MOV   D,C       ) Shift 8 pos in one
        MOV   C,B       ) time
        MVI   B,:00     )
        SUB   L         Update nr of shifts left
        JNZ   :EB57     Again if not ready
 REM
* Shift 1 bit:
 REM
L1E186  ORA   A
        RZ              Abort if ready
        MOV   L,A       L is nr of shifts
L1E187  ORA   A
        CALL  :EB70     Shift BCDE right one bit
        DCR   L         Update shift count
        JNZ   :EB67     Again if not ready
        RET
*
********************
* DIVIDE BCDE BY 2 *
********************
*
* Shifts contents BCDE right 1 position.
*
* Exit: AF corrupted, HL preserved.
*
L1E188  MOV   A,B
        RAR             Shift right B
        MOV   B,A
        MOV   A,C
        RAR             Shift right C
        MOV   C,A
        MOV   A,D
        RAR             Shift right D
        MOV   D,A
        MOV   A,E
        RAR             Shift right E
        MOV   E,A
        RET
*
*************************************
* CHANGE SIGN OF A NUMBER IN MEMORY *
* NEGATE CONTENTS REGISTERS B,C,D,E *
*************************************
*
* Entry: HL points to 1st byte mantissa.
*
L1E189  DCX   H         Pnts to exp
        MOV   A,M       Get exp
        XRI   :80       Change sign bit
        MOV   M,A
L1E190  XRA   A
        MOV   L,A       L=0
        SUB   E
        MOV   E,A       Negate E
        MOV   A,L
        SBB   D
        MOV   D,A       Negate D
        MOV   A,L
        SBB   C
        MOV   C,A       Negate C
        MOV   A,L
        SBB   B
        MOV   L,A       Negated B in L
        ANA   B
        RAL             msb into CY
        MOV   B,L       B = negated B
        MOV   A,L
        RAR             restore msb
        ADC   A         A=2*A+CY
        RET
*
*********************************************
* NORMALIZE CONTENTS BCDE, CORRECT EXPONENT *
*********************************************
*
* Entry: FPT mantissa in BCDE, exponent in MACC.
*
* Mantissa is normalized and the exponent is
* adjusted correctly.
*
L1E191  CALL  :EBA0     Normalize BCDE
        CNC   :C1B7     Add exponents if BCDE<>0
        CMC
        RAR
        ORA   A
        RET
*
*
*
******************************
* NORMALIZE CONTENTS B,C,D,E *
******************************
*
* Shifts contents BCDE left until the msb = 1.
*
* Exit: A: Minus number of shifts.
*       HL restored, S+Z-flag set on result.
*       CY=1: BCDE was zero.
*
L1E192  PUSH  H
        MVI   L,:20     Max 32 bits to shift
L1E193  MOV   A,B       Get 1st byte
        ORA   A
        JNZ   :EBBA     If '1'-bits in it
 REM
* Shift 8 bits at once:
 REM
        MOV   B,C       )
        MOV   C,D       ) Shift 1 byte
        MOV   D,E       )
        MOV   E,A       )
        MOV   A,L
        SUI   :08       Count minus 8 bits
        MOV   L,A
        JNZ   :EBA3     Continue if not ready
        POP   H
        STC             If 4* 8 bits shifted and no
 REM '1' found: BCDE was 0: CY=1
        RET
 REM
* Shift 1 bit:
 REM
L1E194  DCR   L         Update count
        CALL  :EB48     Shift BCDE 1 bit left
L1E195  JP    :EBB6     Again if msb <> 0
 REM
* If ready:
 REM
        MOV   A,L       Get nr of shifts left
        SUI   :20       Calc neg nr of shifts done
        ORA   A
        POP   H
        RET
*
*********
* ROUND *
*********
*
* Rounds up a FPT mantissa in BCD(E). Result in
* MACC, exponent also in E.
*
* Entry: FPT mantissa in BCDE.
* Exit:  CY=1: overflow.
*        All registers corrupted.
*
L1E196  MOV   A,E       Get lobyte mantissa
        ORA   A
        CM    :EBD1     Round up BCD if (E)
 REM >= #80
        RC              Abort if overflow
        LXI   H,:00D5   Addr MACC
        MOV   E,M       Get exp in E
        MOV   A,M       and in A
        JMP   :E9DB     Copy ABCD into MACC
*
* ROUND UP CONTENTS B,C,D:
*
* Increments a FPT mantissa in BCD with 1 in
* the lsb. If required, the normalized exponent
* is adjusted.
*
* Exit: CY=1: Overflow.
*       AEHL preserved.
*
L1E197  INR   D         Add 1 to lobyte
        RNZ
        INR   C         ) Add 1 to other bits to
        RNZ             ) if overflow
        INR   B         )
        RNZ
        MVI   B,:80     If overflow from B: Set B
 REM for smallest mantissa and
 REM increment exponent
*
************************************
* INCREMENT A FPT EXPONENT OF MACC *
************************************
*
* Exit: ABCDEHL preserved. CY=1: overflow.
*
L1E198  PUSH  B
        PUSH  PSW
        PUSH  H
        MVI   A,:01     1 to be added to exponent
L1E199  LXI   H,:00D5   Addr MACC
        CALL  :C1BA     Add 1 to exponent
        POP   H
        POP   B
        MOV   A,B
        POP   B
        RET
*
***********************************************
* DECREMENT FPT EXPONENT OF MACC - (not used) *
***********************************************
*
L1E274  PUSH  B
        PUSH  PSW
        PUSH  H
        MVI   A,:FF     -1 to be added to exponent
        JMP   :EBDE     Add it to MACC exp
*
***************************
* TEST IF OPERAND IS ZERO *
***************************
*
* TSTZA: Test if contents MACC is zero.
* TSTZ:  Test if operand, pointed at by HL, is
*        zero.
*
* Exit: A: hibyte operand.
*       BCDE preserved.
*       HL points to 1st byte of operand.
*       Z=1: Operand = 0.
*
TSTZA   LXI   H,:00D5   Operand = MACC
TSTZ    MOV   A,M
        INX   H
        ORA   M
        INX   H
        ORA   M
        INX   H
        ORA   M         Flags set on result OR
 REM on all bytes of operand
        DCX   H
        DCX   H
        DCX   H
        MOV   A,M       Hibyte operand in A
        RET
*
*
*
        END
